<?php

namespace core\lib\upload;

use Exception;
use Webman\Http\UploadFile;

class UploadBase implements Iupload
{
    public $uploadpath; //上传物理路径
    public $visitpath = ''; //网络查看路径
    public $ext      = 'png,jepg,jpg';
    public $size     = 1024 * 1024 * 8;  //限制大小
    public $ispublic = true; //true 公开访问 存放到public 目录下 否则 存 runtime目录下
    public $path     = ''; //路径后缀

    public function __construct(
        string $ext = 'png,jepg,jpg',
        int $size = 1024 * 1024 * 8,
        bool $ispublic = true,
        string $path = ''
    ) {
        //用插件和控制名作为目录


        $this->ext      = $ext;
        $this->size     = $size;
        $this->ispublic = $ispublic;
        // $this->path     = $plugin . '/' . $controllepath . '/' . $path;
        $this->path     =  $path == '' ? '' : $path . '/';


        $this->uploadpath =
            $this->ispublic ? public_path() . '/upload/'  .   $this->path  :
            runtime_path() . '/storage/' . $this->path;

        $this->visitpath =
            $this->ispublic ?   '/upload/'  . $this->path  :
            '/runtime/storage/' . $this->path;
    }

    /**
     * 检查后缀
     *
     * @param UploadFile $spl_file
     * @return boolean
     */
    protected function chkExt(UploadFile $spl_file): bool
    {
        $exts = explode(',', $this->ext);
        return in_array('.' . $spl_file->getUploadExtension(), $exts);
    }

    /**
     * 检查大小
     *
     * @param UploadFile $spl_file
     * @return boolean
     */
    protected function chkSize(UploadFile $spl_file): bool
    {
        return $spl_file->getSize() <= $this->size;
    }


    /**
     * 检查上传文件是否有效
     *
     * @param UploadFile $spl_file
     * @return boolean
     */
    protected function chkValid(UploadFile $spl_file): bool
    {
        return $spl_file->isValid();
    }


    /**
     * 检查上传文件
     *
     * @param UploadFile $spl_file
     * @throws Exception
     * @return void
     */
    protected function chkUploadFile(UploadFile $spl_file)
    {
        if (!$this->chkValid($spl_file)) {
            throw new Exception($spl_file->getUploadName() . '文件无效');
        }

        if (!$this->chkSize($spl_file)) {
            throw new Exception($spl_file->getUploadName() . '文件大小超出限制');
        }

        if (!$this->chkExt($spl_file)) {
            throw new Exception($spl_file->getUploadName() . '文件格式无效');
        }
    }

    /**
     * 获取上传的文件名
     *
     * @param UploadFile $spl_file
     * @param boolean $ext 是否带扩展名
     * @return string
     */
    protected function getUploadName(UploadFile $spl_file, bool $ext = true): string
    {
        if ($ext) {
            return $spl_file->getUploadName();
        }

        $ext = '.' . $spl_file->getUploadExtension();

        return substr($spl_file->getUploadName(), 0, -strlen($ext));
    }


    /**
     * 上传文件
     *
     * @return array
     */
    public function upload(): array
    {
        $files = [];
        foreach (request()->file() as $key => $spl_file) {
            try {
                $this->chkUploadFile($spl_file);
            } catch (Exception $ex) {
                throw $ex;
            }

            try {
                $size        = $spl_file->getSize();
                $newfilename = time() . rand(1, 9999);
                $filename    = $newfilename . '.' . $spl_file->getUploadExtension();
                $filepath    = $this->uploadpath . $filename;
                $spl_file->move($filepath);
                $files[] = [
                    'path'         => $this->visitpath . $filename,
                    'newfilename'  => $newfilename,
                    'orgname'      => $this->getUploadName($spl_file),
                    'orgnamenoext' => $this->getUploadName($spl_file, false),
                    'size'         => $size
                ];
            } catch (Exception $ex) {
                throw $ex;
            }
        }
        return  count($files) == 1 ? $files[0] : $files;
    }
}
